package ar.com.sectorwine.controllers;

import java.security.Principal;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import excepciones.ExcepcionGeneral;

import ar.com.sectorwine.dto.EmpresaDTO;
import ar.com.sectorwine.dto.EmpresasDTOMapper;
import ar.com.sectorwine.dto.UsuarioABMDTO;
import ar.com.sectorwine.dto.UsuarioABMDTOMapper;
import ar.com.sectorwine.entities.Empresa;
import ar.com.sectorwine.entities.Users;
import ar.com.sectorwine.services.EmpresasService;
import ar.com.sectorwine.services.UsuarioService;

/**
 * Handles requests for the application home page.
 */
@Controller
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class ConfigurarController {

	@Autowired
	private UsuarioService usuarioService;

	@Autowired
	private EmpresasService empresasService;

	@Autowired
	private EmpresasDTOMapper empresasDTOMapper;

	@Autowired
	private Validator validator;

	@Autowired
	private UsuarioABMDTOMapper usuarioABMDTOMapper;

	private static final Logger logger = LoggerFactory
			.getLogger(RegistroController.class);

	@RequestMapping(value = "configurar", method = RequestMethod.GET)
	public ModelAndView modificar(Locale locale, Model model,
			Principal principal) {

		logger.info("Welcome home! the client locale is " + locale.toString());

		ModelAndView mav = new ModelAndView("settings/cuenta");

		Users usuario_buscado = usuarioService.getUsuario(principal.getName());

		mav.addObject("usuario", usuarioABMDTOMapper
				.obtenerDTODesdeObjetoDelDominio(usuario_buscado));
		if (!(usuario_buscado.getPerfilUsuario().getEmpresas().isEmpty())) {
			mav.addObject("mis_empresas", usuario_buscado.getPerfilUsuario()
					.getEmpresas());
		} else {
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa asociada a tu perfil.");
			logger.info("El usuario " + usuario_buscado.getUsername()
					+ " no tiene empresa creada.");
		}
		List<UsuarioABMDTO> usuarios = ChatController.obtenercontactos(principal.getName(), usuarioService, usuarioABMDTOMapper);
		mav.addObject("usuarios", usuarios);
		return mav;
	}

	@RequestMapping(value = "modificar_cuenta", method = RequestMethod.POST)
	public ModelAndView modificar(
			@Valid @ModelAttribute("usuario") UsuarioABMDTO usuarioDTO,
			BindingResult result, SessionStatus status, Principal principal) {

		logger.info("controller");
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		Users usuario = usuarioABMDTOMapper
				.obtenerObjetoDelDominioDesdeDTO(usuarioDTO);

		Set<ConstraintViolation<UsuarioABMDTO>> failures = validator
				.validate(usuarioDTO);
		List<UsuarioABMDTO> usuarios = ChatController.obtenercontactos(principal.getName(), usuarioService, usuarioABMDTOMapper);

		if (failures.size() == 0) {
			if (usuario != null) {
				usuarioService.modificarUsuario(usuario);
				status.setComplete();
				ModelAndView mav = new ModelAndView("settings/cuenta");
				mav.addObject("usuario", usuarioDTO);
				mav.addObject("mensajeCabecera",
						"El usuario '" + usuarioDTO.getUsername()
								+ "' se modifico de manera exitosa!");
				if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
					mav.addObject("mis_empresas", usuarioActual
							.getPerfilUsuario().getEmpresas());
				} else {
					mav.addObject("mensajeCabecera",
							"Aun no tienes una empresa asociada a tu perfil.");
					logger.info("El usuario " + usuarioActual.getUsername()
							+ " no tiene empresa creada.");
				}
				mav.addObject("usuarios", usuarios);
				return mav;
			} else {
				ModelAndView mav = new ModelAndView("settings/cuenta");
				mav.addObject("usuario", usuarioDTO);
				mav.addObject("usuarios", usuarios);
				return mav;
			}
		} else {
			ModelAndView mav = new ModelAndView("settings/cuenta");
			mav.addObject("usuario", usuarioDTO);
			mav.addObject(
					"mensajeCabecera",
					"Hay un error en uno de los campos requeridos, por favor revise las correcciones");
			for (Object o : failures) {
				logger.info(o.toString());
			}
			mav.addObject("usuarios", usuarios);
			return mav;
		}

	}
	
	@RequestMapping(value = "suscripciones", method = RequestMethod.GET)
	public ModelAndView suscripciones(Locale locale, Model model,
			Principal principal) {

		logger.info("Welcome home! the client locale is " + locale.toString());

		ModelAndView mav = new ModelAndView("settings/suscripciones");

		Users usuario_buscado = usuarioService.getUsuario(principal.getName());

		if (!(usuario_buscado.getPerfilUsuario().getEmpresas().isEmpty())) {
			mav.addObject("mis_empresas", usuario_buscado.getPerfilUsuario()
					.getEmpresas());
		} else {
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa asociada a tu perfil.");
			logger.info("El usuario " + usuario_buscado.getUsername()
					+ " no tiene empresa creada.");
		}
		List<UsuarioABMDTO> usuarios = ChatController.obtenercontactos(principal.getName(), usuarioService, usuarioABMDTOMapper);
		mav.addObject("usuarios", usuarios);
		return mav;
	}

	@RequestMapping(value = "cuenta_baja", method = RequestMethod.POST)
	public ModelAndView darBajaLogica(Locale locale, Model model,
			Principal principal) {

		logger.info("controller");

		ModelAndView mav = new ModelAndView("j_spring_security_logout");

		Users usuario_buscado = usuarioService.getUsuario(principal.getName());
		mav.addObject("resultado", usuarioService.bajaUsuario(usuario_buscado));

		return mav;
	}

	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "sitio_configurar", method = RequestMethod.GET)
	public ModelAndView modificar(Locale locale, @RequestParam String id,
			Model model, Principal principal) {

		logger.info("Welcome home! the client locale is " + locale.toString());

		ModelAndView mav = new ModelAndView("settings/sitio_configurar");

		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		Empresa empresa_buscada = empresasService.getEmpresa(id);
		mav.addObject("empresa", empresa_buscada);

		if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
			mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
					.getEmpresas());
		}
		List<UsuarioABMDTO> usuarios = ChatController.obtenercontactos(principal.getName(), usuarioService, usuarioABMDTOMapper);
		mav.addObject("usuarios", usuarios);
		return mav;
	}

	@RequestMapping(value = "sitio_configurar", method = RequestMethod.POST)
	public ModelAndView modificar(
			@Valid @ModelAttribute("empresa") EmpresaDTO empresaDTO,
			BindingResult result, SessionStatus status, Principal principal) {

		logger.info("controller");
		Empresa empresa = empresasDTOMapper
				.obtenerObjetoDelDominioDesdeDTO(empresaDTO);
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		Set<ConstraintViolation<EmpresaDTO>> failures = validator
				.validate(empresaDTO);
		List<UsuarioABMDTO> usuarios = ChatController.obtenercontactos(principal.getName(), usuarioService, usuarioABMDTOMapper);
		

		if (failures.size() == 0) {
			if (empresa != null) {
				try {
					empresasService.modificarEmpresa(empresa);
					status.setComplete();
					ModelAndView mav = new ModelAndView(
							"settings/sitio_configurar");
					mav.addObject("mensajeCabecera",
							"La empresa '" + empresa.getRazonSocial()
									+ "' se modifico con existo!");
					if (!(usuarioActual.getPerfilUsuario().getEmpresas()
							.isEmpty())) {
						mav.addObject("mis_empresas", usuarioActual
								.getPerfilUsuario().getEmpresas());
					}
					mav.addObject("empresa", empresa);
					mav.addObject("usuarios", usuarios);
					return mav;
				} catch (ExcepcionGeneral e) {
					ModelAndView mav = new ModelAndView(
							"settings/sitio_configurar");
					mav.addObject("empresa", empresaDTO);
					if (!(usuarioActual.getPerfilUsuario().getEmpresas()
							.isEmpty())) {
						mav.addObject("mis_empresas", usuarioActual
								.getPerfilUsuario().getEmpresas());
					}
					mav.addObject("usuarios", usuarios);
					mav.addObject("mensajeCabecera", e.getMessage());
					return mav;
				}
			} else {
				ModelAndView mav = new ModelAndView("settings/sitio_configurar");
				if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
					mav.addObject("mis_empresas", usuarioActual
							.getPerfilUsuario().getEmpresas());
				}
				mav.addObject("usuarios", usuarios);
				mav.addObject("empresa", empresaDTO);
				return mav;
			}
		} else {
			ModelAndView mav = new ModelAndView("settings/sitio_configurar");
			mav.addObject("empresa", empresaDTO);
			if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
				mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
						.getEmpresas());
			}
			for (Object o : failures) {
				logger.info(o.toString());
			}
			mav.addObject("usuarios", usuarios);
			return mav;
		}

	}

	@RequestMapping(value = "sitio_baja", method = RequestMethod.POST)
	public ModelAndView darBajaLogica(Locale locale, @RequestParam String id,
			Model model, Principal principal) {

		logger.info("controller");

		ModelAndView mav = new ModelAndView("home");
		mav.addObject("resultado", empresasService.bajaEmpresa(id));
		List<UsuarioABMDTO> usuarios = ChatController.obtenercontactos(principal.getName(), usuarioService, usuarioABMDTOMapper);
		mav.addObject("usuarios", usuarios);
		return mav;
	}

}